﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace zmMoniter
{
    public partial class frmDeck2D : DevExpress.XtraEditors.XtraForm
    {
        #region **************仓面屏幕参数**************
        private double m_xStart;//存储屏幕左下角的实际坐标X
        private double m_yStart;//存储屏幕左下角的实际坐标Y
        private Extent m_Extent;
        private Extent m_MapAllExtent;
        private double m_Blc;//存储屏幕转换比例尺
        private int m_wScreen, m_hScreen;//存储视图屏幕的实际宽度和高度（逻辑坐标）
        public  int m_MapMode;
        public  int m_OldMapMode;
       
        private double m_MouseX, m_MouseY;//鼠标移动轨迹
        private bool m_Move;//是否执行移动地图操作
        private bool m_bSZommIn;//是否执行放大地图操作
        private bool m_bZommOut;//是否执行缩小地图操作
        public  bool bReady;//是否准备好数据了
        private Point m_Point1, m_Point2;//移动时候的起终点坐标
        private bool m_bLBtnDown = false;
        #endregion
        private mainForm main = null;
        Bitmap bmp = null;
        ArrayList alGraph = new ArrayList();//仓面层面图元数组
        ArrayList alVibGraph = new ArrayList();//振捣图元数组
        ArrayList alTitleGraph = new ArrayList();//仓面层面图元数组
        ArrayList alNonVibrGraph = new ArrayList();//非振捣区域图元数组
        ArrayList alSelNonVibrGraph = new ArrayList();//非振捣区域被选图元数组
        ArrayList alPlgGraph = new ArrayList();//非振捣区域临时点位数组
        
        
        Hashtable htDeviceGrap = new Hashtable();
        HashSet<string> setDevice;
        public  string sDeckID = "";
        public  string sDeckName = "";
        public  string sLayerID = "";
        public  string sLayerName = "";
        public  string sDamBlock = "";
        public  bool bWarnFlash=false;
        public  bool bFlash = false;
        public  frmDeck2D(mainForm frm)
        {
            InitializeComponent();
            bReady = false;
            m_Extent = new Extent();
            //updateMapExtent();
            m_MapMode =3;
            m_OldMapMode = 3;
            m_Point1=new Point(0,0);
            m_Point2 = new Point(0, 0);
            this.main = frm;
            bmp=new Bitmap("images/lenged.bmp");
            setDevice = new HashSet<string>();
            htDeviceGrap = new Hashtable();
        }
        public  void addLenged()
        {
           
        }
        private void setCanvas(double dX, double dY, double dBlc)
        {
            m_xStart = dX;
            m_yStart = dY;
            m_Blc = dBlc;
        }
        private void updateMapExtent()
        {
            m_wScreen = this.Canvas.Width;
            m_hScreen = this.Canvas.Height;
            if (m_wScreen != 0 && m_hScreen != 0)
            {
                bReady = true;

                int iScreenSize = m_wScreen > m_hScreen ? m_hScreen : m_wScreen;
                double dMapWSize =m_Extent.dMaxX - m_Extent.dMinX;
                double dMapHSize = m_Extent.dMaxY - m_Extent.dMinY;
                double dMapSize =dMapWSize > dMapHSize?dMapWSize:dMapHSize;

                m_Blc = 1.3*dMapSize / iScreenSize;

                if (m_wScreen > m_hScreen)
                {
                    m_xStart = (m_Extent.dMaxX + m_Extent.dMinX) / 2 - m_wScreen / 2 * m_Blc;
                    m_yStart = (m_Extent.dMaxY + m_Extent.dMinY) / 2 - m_hScreen / 2 * m_Blc;
                }
                else
                {
                    m_xStart = (m_Extent.dMaxX + m_Extent.dMinX) / 2 - m_wScreen / 2 * m_Blc;
                    m_yStart = (m_Extent.dMaxY + m_Extent.dMinY) / 2 - m_hScreen / 2 * m_Blc;
                }
            }
        }
        private void addGraph(Graph gObj)
        {
            alGraph.Add(gObj);
            
        }
        private void clearGraph()
        {
            alGraph.Clear();
            alVibGraph.Clear();
            alTitleGraph.Clear();
            setDevice.Clear();
            //htDeviceGrap.Clear();
            alPlgGraph.Clear();
            alNonVibrGraph.Clear();
            sDeckID = "";
            sDeckName = "";
            sLayerID = "";
            sDamBlock ="";
        }
        private string getDeckTitle(string strDeckName)
        {
            if (strDeckName == "")
                return "";
            string[] str = strDeckName.Split('-');

            string strDam = str[0];
            string strBlock = str[1];
            string strLayer = str[2];
            string sName ="";
           
            sName +=  strDam + "#坝段 ";

             if (strBlock == "S")
                sName += "上游坝块 ";
            else
                 sName += "下游坝块 ";
            sName +=  strDeckName + "仓 ";
            //sName +=  "第"+strLayer + "铺层";
            return sName;
           

        }
        public  void loadDeckData(string sdeckID)
        {
            clearGraph();
            sDeckID = sdeckID;
            sDeckName = "";
            PublicDataCls db = new PublicDataCls();
            db.OpenConn();
            string sSQL = "select 仓面名称,坝段,上下游块,最低高程,最高高程," +
            "铺层厚度,开仓状态,仓面控制点,仓面信息.开仓时间,仓面信息.结束时间 " +
            "from 仓面信息 WHERE 编号=" + sdeckID;
            DataTable dt = db.ReturnDataTable(sSQL);
            db.CloseConn();
            if (dt == null)//modify by lance 2013-1-20
            {
                return;//modify by lance 2013-1-20
            }
            int iCount = dt.Rows.Count;
            if (iCount == 0)
                return;
            DataRow dataRow = dt.Rows[0];
            sDeckName = dataRow["仓面名称"].ToString().Trim();
            sDamBlock = sDeckName.Substring(0, sDeckName.LastIndexOf('-'));
            string strDeckFence = dataRow["仓面控制点"].ToString().Trim();
            float fMinElv= float.Parse(dataRow["最低高程"].ToString().Trim());
            float fMaxElv= float.Parse(dataRow["最高高程"].ToString().Trim());
            Graph gObjTitle = new Graph(1, -1);
            gObjTitle.addText(getDeckTitle(sDeckName));
            gObjTitle.setFont(new Font("微软雅黑", 14f));
            alTitleGraph.Add(gObjTitle);
     

            Graph gObjElv = new Graph(1, -1);
            gObjElv.addText("EL."+fMinElv.ToString()+"m-EL."+fMaxElv.ToString()+"m");
            gObjElv.setFont(new Font("微软雅黑", 12f));
            alTitleGraph.Add(gObjElv);

            string[] sPoints = strDeckFence.Split(';');
            Graph gObj = new Graph(1, 3);
            gObj.setPen(new Pen(Color.Black, 3));
            for (int i = 0; i < sPoints.Length; i++)
            {
                string[] sXY = sPoints[i].Split(',');
                if (sXY.Length == 2)
                {
                    gObj.addPoint(new Point(double.Parse(sXY[0]), double.Parse(sXY[1])));
                    addGraph(gObj);
                }
            }
            reDraw();
        }
        public  void upDateDevicePos(string sDID, string sDeID, float fx, float fy, float fAngle)
        {
            if (sDeckID != sDID)
                return;
            if (htDeviceGrap.ContainsKey(sDeID))
            {
                VibGraph gObj = (VibGraph)htDeviceGrap[sDeID];
                gObj.type = 1;
                gObj.setPos(fx, fy, fAngle);
                gObj.lastDate = DateTime.Now;
                Canvas.Refresh();
            }

        }
        public  void upDateNonVibr()
        {
            alNonVibrGraph.Clear();
            PublicDataCls db = new PublicDataCls();
            db.OpenConn();
            string sSQL = "select 非振捣区域.* from 非振捣区域 WHERE 仓面号=" + sDeckID + " AND 层号=" + sLayerID;
            DataTable dt = db.ReturnDataTable(sSQL);
            db.CloseConn();
            if (dt == null)//modify by lance 2013-1-20
            {
                return;//modify by lance 2013-1-20
            }
            int iCount = dt.Rows.Count;
            if (iCount == 0)
                return;
            for(int i=0;i<iCount;i++)
            {
                DataRow dataRow = dt.Rows[i];
               
                
                double dArea=-1;
                string sArea = dataRow["面积"].ToString().Trim();
                if(sArea!="")
                    dArea = float.Parse(sArea);
                
                int iColor = int.Parse(dataRow["显示颜色"].ToString().Trim());
                string strVbtFence = dataRow["非振捣点位"].ToString().Trim();
                double dCenterX=-1;
                double dCenterY=-1;
               
                NonVibrators nonVibr = new NonVibrators();
                getCenterXY(strVbtFence, ref nonVibr, ref dCenterX, ref dCenterY);
                nonVibr.sName = dataRow["名称"].ToString().Trim();
                nonVibr.sID = dataRow["编号"].ToString().Trim();
                nonVibr.sDisc = dataRow["说明"].ToString().Trim();
                nonVibr.iColor = int.Parse(dataRow["显示颜色"].ToString().Trim());
                nonVibr.dCenterX = dCenterX;
                nonVibr.dCenterY = dCenterY;
                nonVibr.dArea = dArea;
                alNonVibrGraph.Add(nonVibr);
            }
        }
        private void getCenterXY(string strVbtFence, ref NonVibrators alNonVibr, ref double dCenterX, ref double dCenterY)
        {
            string[] strXYs = strVbtFence.Split(';');
            if (strXYs.Length == 0)
                return;
            for (int i = 0; i < strXYs.Length; i++)
            {
                string[] sXY = strXYs[i].Split(',');
                if (sXY.Length != 2)
                    continue;
                double dx = double.Parse(sXY[0]);
                double dy = double.Parse(sXY[1]);
                Point pt = new Point(dx, dy);
                alNonVibr.addPoint(pt);
                dCenterX += dx;
                dCenterY += dy;
            }
            dCenterX = dCenterX * 1.0 / strXYs.Length;
            dCenterY = dCenterY * 1.0 / strXYs.Length;
        }
        public  void upDateLayer(string sdeckID, string slayerName)
        {
            if(sDeckID==sdeckID&&sLayerName==slayerName)
                loadLayerData(sDeckID,sLayerID);
        }
        public  void upDateLayer()
        {
            if (sDeckID != "" && sLayerID!="")
                loadLayerData(sDeckID, sLayerID);
        }
        public  void loadLayerData(string sdeckID,string slayerID)
        {
            clearGraph();
            if (sDeckID != sdeckID)
            {
                getDevice();
            }
            sDeckID = sdeckID;
            
            sLayerID = slayerID;
            PublicDataCls db = new PublicDataCls();
            db.OpenConn();
            string sSQL = "select 铺层信息表.*,仓面信息.仓面名称,仓面信息.坝段,仓面信息.上下游块,仓面信息.最低高程,仓面信息.最高高程," +
            "仓面信息.振捣边界点,仓面信息.铺层厚度,仓面信息.开仓状态,仓面信息.仓面控制点,仓面信息.开仓时间,仓面信息.结束时间 " +
            "from 铺层信息表,仓面信息 WHERE 铺层信息表.仓面号=仓面信息.编号 AND 铺层信息表.编号=" + sLayerID + " AND 铺层信息表.仓面号=" + sdeckID;
            DataTable dt = db.ReturnDataTable(sSQL);
            db.CloseConn();
            if (dt == null)//modify by lance 2013-1-20
            {
                this.main.siInfo.Caption = "数据库连接失败!";
                return;//modify by lance 2013-1-20
            }
            this.main.siInfo.Caption = "";
            int iCount = dt.Rows.Count;
            if (iCount == 0)
                return;
            DataRow dataRow = dt.Rows[0];
            sDeckName = dataRow["仓面名称"].ToString().Trim();
            sLayerName = dataRow["层编号"].ToString().Trim();
            
            sDamBlock = sDeckName.Substring(0, sDeckName.LastIndexOf('-'));
          //  float fArea = float.Parse(dataRow["剩余未振捣面积"].ToString().Trim());
            float fhMin = float.Parse(dataRow["最低高程"].ToString().Trim());
            float fhMax = float.Parse(dataRow["最高高程"].ToString().Trim());
            string strDeckFence=dataRow["仓面控制点"].ToString().Trim();
            string strVbtFence = dataRow["振捣边界点"].ToString().Trim();
            string strLayerFence = dataRow["层边界控制点"].ToString().Trim();

            Graph gObjTitle = new Graph(1, -1);
            gObjTitle.addText(getDeckTitle(sDeckName));
            gObjTitle.setFont(new Font("微软雅黑", 14f));

            alTitleGraph.Add(gObjTitle);
            
            

            Graph gObjElv = new Graph(1, -1);
            gObjElv.addText("EL." + fhMin.ToString() + "m-EL." + fhMax.ToString() + "m 第" + sLayerName + "铺层");
            gObjElv.setFont(new Font("微软雅黑", 12f));
            alTitleGraph.Add(gObjElv);

            string[] sPoints = strDeckFence.Split(';');
            Graph gObj = new Graph(1, 3);
            gObj.setPen(new Pen(Color.Black, 3));
            for (int i = 0; i < sPoints.Length; i++)
            {
                string[] sXY = sPoints[i].Split(',');
                if (sXY.Length == 2)
                {
                    gObj.addPoint(new Point(double.Parse(sXY[0]), double.Parse(sXY[1])));
                    addGraph(gObj);
                }
            }
            getVibrators();

            sPoints = strVbtFence.Split(';');
            gObj = new Graph(1, 3);
            gObj.setPen(new Pen(Color.Blue, 1));
            for (int i = 0; i < sPoints.Length; i++)
            {
                string[] sXY = sPoints[i].Split(',');
                if (sXY.Length == 2)
                {
                    gObj.addPoint(new Point(double.Parse(sXY[0]), double.Parse(sXY[1])));
                    addGraph(gObj);
                }
            }

            sPoints = strLayerFence.Split(';');
            gObj = new Graph(1, 3);
            gObj.setPen(new Pen(Color.Orange, 1));
            for (int i = 0; i < sPoints.Length; i++)
            {
                string[] sXY = sPoints[i].Split(',');
                if (sXY.Length == 2)
                {
                    gObj.addPoint(new Point(double.Parse(sXY[0]), double.Parse(sXY[1])));
                    addGraph(gObj);
                }
            }
            upDateNonVibr();
            flashTimer.Enabled = true;
            
            reDraw();
        }
        public  void getDevice()
        {
            PublicDataCls db = new PublicDataCls();
            db.OpenConn();
            string sSQL = "select * FROM 振捣设备基本信息表";

            DataTable dt = db.ReturnDataTable(sSQL);
            db.CloseConn();
            if (dt == null)//modify by lance 2013-1-20
            {
                return;//modify by lance 2013-1-20
            }
            int iCount = dt.Rows.Count;
            if (iCount == 0)
                return;
            for (int i = 0; i < iCount; i++)
            {
                DataRow dataRow = dt.Rows[i];


                string strDeviceID = dataRow["编号"].ToString().Trim();
                string strDeviceCN = dataRow["型号"].ToString().Trim();
                string strDeviceFence = dataRow["振动影响区域"].ToString().Trim();
                string strDeviceHeadNum = dataRow["振动棒数量"].ToString().Trim();
                string[] sPoints = strDeviceFence.Split(';');
                
                VibGraph gDeviceObj = new VibGraph(1, -1);
                if (strDeviceID == "1")
                {
                    //setDevice.Add(strDeviceID);
                    gDeviceObj.addText(strDeviceCN);
                    gDeviceObj.setPen(new Pen(Color.FromArgb(255, ColorTranslator.FromWin32(Properties.Settings.Default.ep_color1)), 1));
                }
                else if (strDeviceID == "2")
                {
                    //setDevice.Add(strDeviceID);
                    gDeviceObj.addText(strDeviceCN);
                    gDeviceObj.setPen(new Pen(Color.FromArgb(255, ColorTranslator.FromWin32(Properties.Settings.Default.ep_color2)), 1));
                }
                else if (strDeviceID == "3")
                {
                    //setDevice.Add(strDeviceID);
                    gDeviceObj.addText(strDeviceCN);
                    gDeviceObj.setPen(new Pen(Color.FromArgb(255, ColorTranslator.FromWin32(Properties.Settings.Default.ep_color3)), 1));
                }
                else if (strDeviceID == "4")
                {
                    setDevice.Add(strDeviceID);
                    gDeviceObj.addText(strDeviceCN);
                    gDeviceObj.setPen(new Pen(Color.FromArgb(255, ColorTranslator.FromWin32(Properties.Settings.Default.ep_color4)), 1));
                }
                else if (strDeviceID == "5")
                {
                    //setDevice.Add(strDeviceID);
                    gDeviceObj.addText(strDeviceCN);
                    gDeviceObj.setPen(new Pen(Color.FromArgb(255, ColorTranslator.FromWin32(Properties.Settings.Default.ep_color5)), 1));
                }
                else if (strDeviceID == "6")
                {
                    //setDevice.Add(strDeviceID);
                    gDeviceObj.addText(strDeviceCN);
                    gDeviceObj.setPen(new Pen(Color.FromArgb(255, ColorTranslator.FromWin32(Properties.Settings.Default.ep_color6)), 1));
                }
                else if (strDeviceID == "7")
                {
                    //setDevice.Add(strDeviceID);
                    gDeviceObj.addText(strDeviceCN);
                    gDeviceObj.setPen(new Pen(Color.FromArgb(255, ColorTranslator.FromWin32(Properties.Settings.Default.ep_color7)), 1));
                }
                else if (strDeviceID == "8")
                {
                    //setDevice.Add(strDeviceID);
                    gDeviceObj.addText(strDeviceCN);
                    gDeviceObj.setPen(new Pen(Color.FromArgb(255, ColorTranslator.FromWin32(Properties.Settings.Default.ep_color8)), 1));
                }
                else
                {
                    //setDevice.Add(strDeviceID);
                    gDeviceObj.addText(strDeviceCN);
                    gDeviceObj.setPen(new Pen(Color.FromArgb(160, ColorTranslator.FromWin32(Properties.Settings.Default.ep_color8)), 1));
                }

                for (int j = 0; j < sPoints.Length; j++)
                {
                    string[] sXY = sPoints[j].Split(',');
                    if (sXY.Length == 2)
                    {
                       
                        Point pt = new Point(double.Parse(sXY[0]), double.Parse(sXY[1]));
                        gDeviceObj.addPoint(pt);
                    }
                }

                if (!htDeviceGrap.ContainsKey(strDeviceID))
                    htDeviceGrap.Add(strDeviceID, gDeviceObj);
            }
        }
        public  void getVibrators()
        {
            alVibGraph.Clear();
            setDevice.Clear();
            PublicDataCls db = new PublicDataCls();
            db.OpenConn();
            string sSQL = "select 振捣监控点位数据表.*,"+
            "振捣设备基本信息表.编号 as 设备编号,振捣设备基本信息表.型号,振捣设备基本信息表.振动棒数量,振捣设备基本信息表.履带长," +
            "振捣设备基本信息表.履带宽,振捣设备基本信息表.棒头头长,"+
            "振捣设备基本信息表.棒头总长,振捣设备基本信息表.振动影响区域,振捣设备基本信息表.使用设备状态 "+
            "FROM 振捣监控点位数据表 LEFT OUTER JOIN "+
            "振捣设备基本信息表 ON 振捣监控点位数据表.设备编号 = 振捣设备基本信息表.编号 "+
            "WHERE 振捣监控点位数据表.铺层编号="+sLayerName+
            " AND 振捣监控点位数据表.仓面号="+sDeckID;

            DataTable dt = db.ReturnDataTable(sSQL);
            db.CloseConn();
            if (dt == null)//modify by lance 2013-1-20
            {
                return;//modify by lance 2013-1-20
            }
            int iCount = dt.Rows.Count;
            if (iCount == 0)
                return;
            for (int i = 0; i < iCount; i++)
            {
                DataRow dataRow = dt.Rows[i];

                float fX = float.Parse(dataRow["X"].ToString().Trim());
                float fY = float.Parse(dataRow["Y"].ToString().Trim());
                string strVibID = dataRow["设备编号"].ToString().Trim();
                string strVibCN = dataRow["型号"].ToString().Trim();
                string strVibFence = dataRow["振动影响区域"].ToString().Trim();
                float fVibAngle = float.Parse(dataRow["振捣方位角"].ToString().Trim());
                string[] sPoints = strVibFence.Split(';');
                Graph gObj = new Graph(1, 31);
               

                if (htDeviceGrap.ContainsKey(strVibID))
                {
                    VibGraph gDeviceObj = (VibGraph)htDeviceGrap[strVibID];
                    gObj.setPen(gDeviceObj.pen);
                    setDevice.Add(strVibCN);
                }

                for (int j = 0; j < sPoints.Length; j++)
                {
                    string[] sXY = sPoints[j].Split(',');
                    if (sXY.Length == 2)
                    {
                        gObj.addPoint(angleTranslate(fX, fY, double.Parse(sXY[0]), double.Parse(sXY[1]), fVibAngle * Math.PI / 180));
                    }
                }
                alVibGraph.Add(gObj);
                
            }
        }
        
        public  void setMapMode(int imapMode)
        {
            m_MapMode = imapMode;
            m_OldMapMode = m_MapMode;
            if (m_MapMode == 1)//放大
            {
                this.Cursor = Cursors.Arrow;
            }
            else if (m_MapMode == 2)//缩小
            {
                this.Cursor = Cursors.Arrow;
            }
            else if (m_MapMode == 3)//拖动
            {
                this.Cursor =Cursors.Hand;
            }
            else if (m_MapMode == 4)//全图
            {
                 this.Cursor =Cursors.Arrow;
            }
            else if (m_MapMode == 5)//全图
            {
                this.Cursor = Cursors.Cross;
            }
        }
        public  void reDraw()
        {
            m_Extent.reSet();
            for (int i = 0; i < alGraph.Count; i++)
            {
                Graph gObj = (Graph)alGraph[i];
                m_Extent.upDate(gObj.extent);
                m_MapAllExtent = m_Extent;
            }
            Canvas.Refresh();
        }
        #region **************仓面坐标转换操作函数**************
        public int DLtoVL(double l)
        {
            return (int)(l / m_Blc);                                //返回实际坐标表示的长度值
        }
        public double VLtoDL(int l)
        {
            return (double)(l * m_Blc);                             //返回逻辑坐标表示的长度值
        }
        public void VPtoDP(int x, int y, ref double X, ref double Y) //将逻辑坐标转换成实际坐标
        {
            X = m_xStart + x * m_Blc;
            Y = m_yStart + m_Blc * (m_hScreen - y);
        }
        public double VPtoDPX(int x) //将逻辑坐标转换成实际坐标
        {
            return m_xStart + x * m_Blc;
        }
        public double VPtoDPY(int y) //将逻辑坐标转换成实际坐标
        {
            return m_yStart + m_Blc * (m_hScreen - y);
        }
        public void DPtoVP(double x, double y, ref int X, ref int Y) //将实际坐标换成逻辑坐标转
        {
            X = (int)((x - m_xStart) / m_Blc);
            Y = m_hScreen - (int)((y - m_yStart) / m_Blc);
            //Y = (int)((m_yStart - y) / blc);
        }
        public int DPtoVPX(double x) //将实际坐标换成逻辑坐标转
        {
            return (int)((x - m_xStart) / m_Blc);
        }
        public int DPtoVPY(double y) //将实际坐标换成逻辑坐标转
        {
            return m_hScreen - (int)((y - m_yStart) / m_Blc);
            //return (int)((m_yStart - y) / blc);
        }
        #endregion
        

        #region **************绘图函数**************
        private void Canvas_Paint(object sender, PaintEventArgs e)
        {
            updateMapExtent();
            if (!bReady)
                return;
            Graphics g = e.Graphics; //创建画板,这里的画板是由Form提供的.
            g.Clear(Color.White);
            #region **************画标题**************
            if(alTitleGraph.Count>=2)
            {
                Graph gObj1 = (Graph)alTitleGraph[0];
                Graph gObj2 = (Graph)alTitleGraph[1];
                SizeF sizeF1 = g.MeasureString(gObj1.sText, gObj1.font);
                g.DrawString(gObj1.sText, gObj1.font, Brushes.Black,
                                    m_wScreen / 2 - sizeF1.Width / 2, 30);
                SizeF sizeF2 = g.MeasureString(gObj2.sText, gObj2.font);
                g.DrawString(gObj2.sText, gObj2.font, Brushes.Black,
                                    m_wScreen / 2 - sizeF2.Width / 2, 55);
            }
            #endregion
            #region **************画仓面**************
            for (int i = 0; i < alGraph.Count; i++)
            {
                Graph gObj = (Graph)alGraph[i];
                switch (gObj.type)
                {
                    case -1://文字
                        {
                           
                            SizeF sizeF = g.MeasureString(gObj.sText, gObj.font);
                            g.DrawString(gObj.sText, gObj.font, Brushes.Black,
                                m_wScreen/2-sizeF.Width / 2, 30);
                             
                            break;
                        }
                    case 3://面 
                        {
                            int iLength = gObj.alPoint.Count;
                            System.Drawing.Point[] pts = new System.Drawing.Point[iLength];
                            for (int j = 0; j < iLength; j++)
                            {
                                int iVPX = DPtoVPX(gObj.getPointX(j));
                                int iVPY = DPtoVPY(gObj.getPointY(j));
                                pts[j] = new System.Drawing.Point(iVPX, iVPY);
                            }

                            g.DrawPolygon(gObj.pen, pts);

                            pts = null;
                            break;
                        }
                    default:
                        break;
                }
            }
            #endregion
            #region **************画振捣点位**************
            for (int i = 0; i < alVibGraph.Count; i++)
            {
                Graph gObj = (Graph)alVibGraph[i];
                switch (gObj.type)
                {
                    case 3://面 
                        {
                            int iLength = gObj.alPoint.Count;
                            System.Drawing.Point[] pts = new System.Drawing.Point[iLength];
                            for (int j = 0; j < iLength; j++)
                            {
                                int iVPX = DPtoVPX(gObj.getPointX(j));
                                int iVPY = DPtoVPY(gObj.getPointY(j));
                                pts[j] = new System.Drawing.Point(iVPX, iVPY);
                            }

                            g.DrawPolygon(gObj.pen, pts);

                          
                            pts = null;
                            break;
                        }
                    case 31://填充面 
                        {

                            int iLength = gObj.alPoint.Count;
                            System.Drawing.Point[] pts = new System.Drawing.Point[iLength];
                            for (int j = 0; j < iLength; j++)
                            {
                                int iVPX = DPtoVPX(gObj.getPointX(j));
                                int iVPY = DPtoVPY(gObj.getPointY(j));
                                pts[j] = new System.Drawing.Point(iVPX, iVPY);
                            }
                            g.DrawPolygon(gObj.pen, pts);

                            SolidBrush opaqueBrush = new SolidBrush(gObj.pen.Color);
                            g.FillPolygon(opaqueBrush, pts, FillMode.Alternate);

                            pts = null;
                            break;
                        }
                    default:
                        break;
                }
            }

            #endregion
            #region **************画机械轨迹点位**************
            if (bFlash)
            {
                foreach (DictionaryEntry de in htDeviceGrap)
                {
                    VibGraph gDeviceObj = (VibGraph)de.Value;
                    if (gDeviceObj.type!=1||gDeviceObj.alPoint.Count == 0)
                        continue;
                    
                    TimeSpan now = new TimeSpan(DateTime.Now.Ticks); 
                    TimeSpan cur = new TimeSpan(gDeviceObj.lastDate.Ticks); 
                    TimeSpan diff = now.Subtract(cur); 
                    if (diff.TotalSeconds > 30) 
                    {
                         gDeviceObj.type = -1;
                         continue;
                    } 
                    if (gDeviceObj.alPoint.Count > 0)
                    {
                        int iLength = gDeviceObj.alNewPoint.Count;
                        System.Drawing.Point[] pts = new System.Drawing.Point[iLength];
                        for (int j = 0; j < iLength; j++)
                        {
                            int iVPX = DPtoVPX(gDeviceObj.getNewPointX(j));
                            int iVPY = DPtoVPY(gDeviceObj.getNewPointY(j));
                            pts[j] = new System.Drawing.Point(iVPX, iVPY);
                        }
                        g.DrawPolygon(gDeviceObj.pen, pts);
                        SolidBrush opaqueBrush = new SolidBrush(gDeviceObj.pen.Color);
                        g.FillPolygon(opaqueBrush, pts, FillMode.Alternate);
                        pts = null;
                    }
                }
            }
            #endregion
            #region **************画无效区域**************
            DrawNonVibrGraph(ref g);
            if (m_MapMode == 5)
            {
                DrawNonPlgGraph(ref g);
            }
            
            #endregion 
            #region ************是否预警闪烁****************
            if (bWarnFlash)//预警闪烁
            {
                DrawWarning(sDamBlock, sDeckName + "-" + sLayerID, ref g);
            }
             #endregion
            #region **************画图例**************

            //g.DrawImage(bmp, m_wScreen - 210, m_hScreen - 260);


            int iHeight = setDevice.Count*20 + 50;
            g.DrawRectangle(new Pen(Color.Black, 1), m_wScreen - 150, m_hScreen - iHeight, 140, iHeight-10);

            Font font = new Font("微软雅黑", 12f);
            //PointF pointF = new PointF(m_wSScreen/2-100,30);
           
            SizeF sizeLengedF = g.MeasureString("图例", font);
            g.DrawString("图例", font, Brushes.Black,
                                m_wScreen - (150+sizeLengedF.Width)/2-5, m_hScreen - iHeight+5);
            font.Dispose();
            int iPos=m_hScreen - iHeight+25;
            foreach (string device in setDevice)
            {
                Bitmap bmp = new Bitmap("images/" + device + ".png");
                g.DrawImage(bmp, m_wScreen - 130, iPos);
                iPos += 20;
            }

            #endregion
            #region **************画缩放框**************
            if (m_MapMode == 1 || m_MapMode == 2)
            {
                if (m_bLBtnDown != true)
                    return;
                g.DrawRectangle(new Pen(Color.Red, 2), (int)m_Point1.dX, (int)m_Point1.dY,
                    (int)(m_Point2.dX - m_Point1.dX), (int)(m_Point2.dY - m_Point1.dY));
            }
            #endregion
        }
        private void DrawNonPlgGraph(ref Graphics g)//画临时非振捣区域——一个图元
        {
            int iCount = alPlgGraph.Count;
            System.Drawing.Point[] temp_pts = new System.Drawing.Point[iCount];
            for (int i = 0; i < alPlgGraph.Count; i++)
            {
                Point pt = (Point)alPlgGraph[i];

                int iVPX = DPtoVPX(pt.getX());
                int iVPY = DPtoVPY(pt.getY());
                temp_pts[i] = new System.Drawing.Point(iVPX, iVPY);
            }
            if (iCount == 1)
            {
                SolidBrush opaqueBrush = new SolidBrush(SystemColors.HotTrack);
                g.FillEllipse(opaqueBrush, temp_pts[0].X - 5, temp_pts[0].Y - 5, 10, 10);
                opaqueBrush.Dispose();
            }
            else if (iCount == 2)
            {
                SolidBrush opaqueBrush = new SolidBrush(SystemColors.HotTrack);
                g.FillEllipse(opaqueBrush, temp_pts[0].X - 5, temp_pts[0].Y - 5, 10, 10);
                g.DrawLine(new Pen(Color.FromArgb(200, 0, 0, 255), 2), temp_pts[0], temp_pts[1]);
                g.FillEllipse(opaqueBrush, temp_pts[1].X - 5, temp_pts[1].Y - 5, 10, 10);
                opaqueBrush.Dispose();
            }
            else if (iCount > 2)
            {
                SolidBrush opaqueBrush = new SolidBrush(Color.FromArgb(200, 255, 0, 0));
                g.FillPolygon(opaqueBrush, temp_pts, FillMode.Alternate);
                opaqueBrush = new SolidBrush(SystemColors.HotTrack);
                for (int j = 0; j < temp_pts.Length; j++)
                {
                    g.FillEllipse(opaqueBrush, temp_pts[j].X - 5, temp_pts[j].Y - 5, 10, 10);
                }
                opaqueBrush.Dispose();
            }
            temp_pts = null;
        }
        private void DrawNonVibrGraph(ref Graphics g)//画正式非振捣区域——多个图元
        {
            for (int k = 0; k < alNonVibrGraph.Count; k++)
            {
                NonVibrators nonVibr = (NonVibrators)alNonVibrGraph[k];
                int iLength =nonVibr.alPlgGraph.Count;
                System.Drawing.Point[] pts = new System.Drawing.Point[iLength];
                for (int i = 0; i < nonVibr.alPlgGraph.Count; i++)
                {
                   Point pt = (Point)nonVibr.alPlgGraph[i];
                   int iVPX = DPtoVPX(pt.getX());
                   int iVPY = DPtoVPY(pt.getY());
                   pts[i] = new System.Drawing.Point(iVPX, iVPY);
                 }
                 if (iLength > 2)
                 {
                     Color cl = Color.FromArgb(nonVibr.iColor);
                     SolidBrush opaqueBrush = new SolidBrush(Color.FromArgb(200, cl.R, cl.G, cl.B));
                     g.FillPolygon(opaqueBrush, pts, FillMode.Alternate);
                     /*  opaqueBrush = new SolidBrush(SystemColors.HotTrack);
                     for (int j = 0; j < pts.Length; j++)
                      {
                         g.FillEllipse(opaqueBrush, pts[j].X - 5, pts[j].Y - 5, 10, 10);
                      }   //不顶点*/
                     opaqueBrush.Dispose();
                 }
                 pts = null;
                 Font ft=new Font("微软雅黑", 9f);
                 SizeF sizeF1 = g.MeasureString(nonVibr.sName, ft);
               　g.DrawString(nonVibr.sName, ft, Brushes.Blue,
                                       DPtoVPX(nonVibr.dCenterX) ,DPtoVPY(nonVibr.dCenterY));
            }  
        }
        private void DrawWarning(string sDamBlock,string sKey,ref Graphics g)
        {
             if (this.main.htWarnDeck.ContainsKey(sDamBlock))
             {
                   Hashtable htWarning = (Hashtable)this.main.htWarnDeck[sDamBlock];             
                   if (htWarning.ContainsKey(sKey))
                   {
                        ArrayList alWarning=(ArrayList)htWarning[sKey];
                        for (int i = 0; i < alWarning.Count; i++)
                        {
                            Warning warn = (Warning)alWarning[i];
                            Brush brsh = Brushes.Red;
                            g.FillEllipse(brsh, DPtoVPX(warn.dX), DPtoVPY(warn.dY), DLtoVL(1), DLtoVL(1));
                        }
                        
                   }
             }
        }
        #endregion
        #region **************画布事件响应函数**************
        private void Canvas_MouseDown(object sender, MouseEventArgs e)
        {
            if (!bReady)
                return;
            if (e.Button == MouseButtons.Middle)
            {
                m_bLBtnDown = true;
                m_Point1.dX = e.X;
                m_Point1.dY = e.Y;
                m_OldMapMode=m_MapMode;
                m_MapMode = 3;
            }
            else if (m_MapMode < 4)
            {
                m_bLBtnDown = true;
                m_Point1.dX = e.X;
                m_Point1.dY = e.Y;
            }
            else if (m_MapMode ==4)
            {
                double dX = VPtoDPX(e.X);
                double dY = VPtoDPY(e.Y);
                alSelNonVibrGraph.Clear();
                for (int i = 0; i < alNonVibrGraph.Count; i++)
                {
                    NonVibrators nonVibr = (NonVibrators)alNonVibrGraph[i];
                    if (nonVibr.extent.inExtent(dX, dY))
                    {
                        if (IsPointInRegion((float)dX, (float)dY, nonVibr))
                        {
                            alSelNonVibrGraph.Add(nonVibr);
                        }
                    }                  
                }
                Canvas.Refresh();
                if (alSelNonVibrGraph.Count > 0)
                {
                    NonVibrators nonVibr = (NonVibrators)alSelNonVibrGraph[0];
                    frmNonVibrator frNonVibr = new frmNonVibrator();//新加非振捣区域窗口
                    
                    frNonVibr.setData(sDeckID, sLayerID, nonVibr.getNonVibrPoints());
                    frNonVibr.setValue(nonVibr.sName, nonVibr.sDisc,nonVibr.dArea.ToString(), Color.FromArgb(nonVibr.iColor));
                    frNonVibr.setID(nonVibr.sID);
                   
                    frNonVibr.setFlag("edit");
                    DialogResult DResult = frNonVibr.ShowDialog();
                    if (DResult == DialogResult.OK)
                    {                    
                        upDateNonVibr();
                        alSelNonVibrGraph.Clear();
                    }
                    Canvas.Refresh();
                }
            }
            else if (m_MapMode == 5 && e.Button == MouseButtons.Left)
            {
                Point pt=new Point(VPtoDPX(e.X),VPtoDPY(e.Y));
                alPlgGraph.Add(pt);
                Canvas.Refresh();
            }
            else if (m_MapMode == 5&&e.Button == MouseButtons.Right)
            {
                clearPlgPoints();
                Canvas.Refresh();
            }
        }
        private void reMoveNonVibr(string sID)
        {
            for (int i = 0; i < alNonVibrGraph.Count; i++)
            {
                NonVibrators nonVibr = (NonVibrators)alNonVibrGraph[i];
                if (nonVibr.sID == sID)
                {
                    alNonVibrGraph.RemoveAt(i);
                    break;
                }
            }
        }

        private void Canvas_MouseMove(object sender, MouseEventArgs e)
        {
            int iX = e.X;
            int iY = e.Y;
            double dX = VPtoDPX(iX);
            double dY = VPtoDPY(iY);
            main.upDateXYInfo(dX,dY);
            if (!bReady)
                return;
            if (m_bLBtnDown == true && m_MapMode<3)
            {
                m_Point2.dX = iX;
                m_Point2.dY = iY;
                Canvas.Refresh();
            }
            else if (m_bLBtnDown == true && m_MapMode == 3)
            {
                m_Point2.dX = iX;
                m_Point2.dY = iY;
                m_Extent.move(VPtoDPX((int)m_Point1.dX) - VPtoDPX((int)m_Point2.dX),
                    VPtoDPY((int)m_Point1.dY) - VPtoDPY((int)m_Point2.dY));
                m_Point1.dX = m_Point2.dX;
                m_Point1.dY = m_Point2.dY;
                Canvas.Refresh();
            }
            else if (m_MapMode == 5)
            {
                if (alPlgGraph.Count == 0)
                    return;
                //Point pt = new Point(VPtoDPX(e.X), VPtoDPY(e.Y));
                //alPlgGraph.Add(pt);
                //Canvas.Refresh();
            }
        }
        private void Canvas_MouseUp(object sender, MouseEventArgs e)
        {
            
            if (!bReady)
                return;
            if (e.Button == MouseButtons.Middle)
            {
                m_bLBtnDown = false;
                m_MapMode = m_OldMapMode;
            }
            if (m_bLBtnDown == true && m_MapMode < 3)
            {
                m_Point2.dX = e.X;
                m_Point2.dY = e.Y;
                m_bLBtnDown = false;

                if (Math.Abs(m_Point1.dX - m_Point2.dX) < 50 && Math.Abs(m_Point1.dX - m_Point2.dX) < 50)
                {
                    m_bLBtnDown = false;
                    return;
                }
                if (m_MapMode==1)
                    m_Extent.upDate(VPtoDPX((int)m_Point1.dX), VPtoDPY((int)m_Point1.dY),
                        VPtoDPX((int)m_Point2.dX), VPtoDPY((int)m_Point2.dY));
                else if (m_MapMode == 2)
                {
                   /* 
                    double dX1 = VPtoDPX((int)m_Point1.dX);
                    double dY1 = VPtoDPY((int)m_Point1.dY);
                    double dX2 = VPtoDPX((int)m_Point2.dX);
                    double dY2 = VPtoDPY((int)m_Point2.dY);
                    double dCenterX=(dX1+dX2)/2;
                    double dCenterY=(dY1+dY2)/2;
                    double dWidth=m_Extent.getWidth();
                    double dHeight=m_Extent.getHeight();
                    m_Extent.upDate(dCenterX - dWidth / 2 * 1, dCenterY - dHeight / 2 * 1,
                        dCenterX + dWidth / 2 * 1, dCenterY + dHeight / 2 * 1);
                   */


                    
                    m_Extent.upDate(m_Extent.dMinX - m_Extent.getWidth() * 0.1, m_Extent.dMinY - m_Extent.getHeight() * 0.1
                        , m_Extent.dMaxX + m_Extent.getWidth() * 0.1, m_Extent.dMaxY + m_Extent.getHeight() * 0.1);
                }
                Canvas.Refresh();
            }
            else if (m_bLBtnDown == true && m_MapMode == 3)
            {
                m_Point2.dX = e.X;
                m_Point2.dY = e.Y;
                
                m_Extent.move(VPtoDPX((int)m_Point1.dX) - VPtoDPX((int)m_Point2.dX),
                    VPtoDPY((int)m_Point1.dY) - VPtoDPY((int)m_Point2.dY));
                Canvas.Refresh();
            }
            m_bLBtnDown = false;
        }
        private void Canvas_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (m_MapMode == 5)
            {
                Point pt = new Point(VPtoDPX(e.X), VPtoDPY(e.Y));
                alPlgGraph.Add(pt);
                frmNonVibrator frNonVibr = new frmNonVibrator();//新加非振捣区域窗口
                frNonVibr.setData(sDeckID, sLayerID, getNonVibrPoints());
                DialogResult DResult=frNonVibr.ShowDialog();
                if (DResult == DialogResult.OK)
                {
                    MessageBox.Show("添加非振捣区域成功！", "添加非振捣区域提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    alPlgGraph.Clear();
                    upDateNonVibr();
                }
                else
                {
                    MessageBox.Show("添加非振捣区域失败！", "添加非振捣区域提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    alPlgGraph.Clear();
                }
                Canvas.Refresh();
                
                setMapMode(3);
            }
        }
        public  void Canvas_MouseWheel(object sender, MouseEventArgs e)
        {
            if (!bReady)
                return;
            if (e.Delta > 0)//e.Delta > 0时鼠标滚轮是向上滚动，
            {
                double sx=0;
                double sy = 0;
                VPtoDP(e.X, e.Y, ref sx, ref sy);
                m_Extent.upDate(m_Extent.dMinX - m_Extent.getWidth() * 0.05, m_Extent.dMinY - m_Extent.getHeight() * 0.05
                    , m_Extent.dMaxX + m_Extent.getWidth() * 0.05, m_Extent.dMaxY + m_Extent.getHeight() * 0.05);
                updateMapExtent();
                Canvas.Refresh();
            }
            else if(e.Delta < 0)//e.Delta < 0时鼠标滚轮向下滚动。
            {
                double sx = 0;
                double sy = 0;
                VPtoDP(e.X, e.Y, ref sx, ref sy);
                m_Extent.upDate(m_Extent.dMinX + m_Extent.getWidth() * 0.05,
                    m_Extent.dMinY + m_Extent.getHeight() * 0.05, m_Extent.dMaxX - m_Extent.getWidth() * 0.05,
                        m_Extent.dMaxY - m_Extent.getHeight() * 0.05);
                updateMapExtent();
                /*    int ix = 0;
                    int iy = 0;
                    DPtoVP(sx, sy, ref ix, ref iy);
                    int iLengthx = ix-e.X;
                    int iLengthy = iy - e.Y;
                    double dX = VLtoDL(iLengthx);
                    double dY = VLtoDL(iLengthy);

                    m_Extent.move(dX, dY);
                    */
                Canvas.Refresh();
            }
            else if (e.Delta== 0)
            {
                m_bLBtnDown = true;
                m_Point1.dX = e.X;
                m_Point1.dY = e.Y;
               // m_MapMode = 4;
                m_OldMapMode = m_MapMode;
                m_MapMode = 3;
            }
         
        }
        private void Canvas_MouseEnter(object sender, EventArgs e)
        {
            Canvas.Focus();
        }
        private void frmDeck2D_Resize(object sender, EventArgs e)
        {
            Canvas.Refresh();
        }
        private void flashTimer_Tick(object sender, EventArgs e)
        {
            bFlash = !bFlash;
            Canvas.Refresh();
        }
        #endregion
        public  void FlashWarning(bool flash)
        {
            bWarnFlash = flash;
            Canvas.Refresh();
        }
        public  string getNonVibrPoints()
        {
            string sResult = "";
            for (int i = 0; i < alPlgGraph.Count; i++)
            {
                Point pt = (Point)alPlgGraph[i];
                if (i == alPlgGraph.Count - 1)
                    sResult += pt.getX() + "," + pt.getY();
                else
                    sResult += pt.getX() + "," + pt.getY() + ";";
            }
            return sResult;
        }
        public  void clearPlgPoints()
        {
            alPlgGraph.Clear();
        }
       
        private Point angleTranslate(double dfx, double dfy, double dx, double dy, double fAngle)
        {
            double sin = Math.Sin(fAngle);
            double cos = Math.Cos(fAngle);

            double x = dx * cos - dy * sin;
            double y = dx * sin + dy * cos;
            return new Point(dfx + x, dfy + y);
        }
        private bool IsPointInRegion(float dX, float dY, NonVibrators gObj)
        {
            using (GraphicsPath myGraphicsPath = new GraphicsPath())
            {
                using (Region myRegion = new Region())
                {
                    myGraphicsPath.Reset();
                    int iLength = gObj.alPlgGraph.Count;
                    System.Drawing.PointF[] pts = new System.Drawing.PointF[iLength];
                    for (int j = 0; j < iLength; j++)
                    {
                        float dTX = (float)gObj.getPointX(j);
                        float dTY = (float)gObj.getPointY(j);
                        pts[j] = new System.Drawing.PointF(dTX, dTY);
                    }
                    myGraphicsPath.AddPolygon(pts);
                    myRegion.MakeEmpty();
                    myRegion.Union(myGraphicsPath);
                    System.Drawing.PointF ptf = new System.Drawing.PointF(dX, dY);

                    bool bInRgn = myRegion.IsVisible(ptf);

                    return bInRgn;
                }
            }
        }
    }
}